<template>
	<div ref="codeEditBox" class="magic-monaco-editor"  />
</template>
<script lang="ts">
import {
	defineComponent, onBeforeUnmount, onMounted, ref, watch,
} from 'vue'
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import * as monaco from 'monaco-editor'
import 'monaco-editor/esm/vs/basic-languages/sql/sql.contribution'
import { editorProps } from './monacoEditorType'
import SQLSnippets from "../plugins/MonacoEditor/snippets"

export default {
	name: 'MonacoEditor',
	props: editorProps,
	setup() {
		return {
			editor: null,
			sqlSnippets: null,
			completionItemProvider:null
		}
	},
	watch: {

		dbs: {
			deep: true,
			async handler() {
				this.sqlSnippets && this.sqlSnippets.setDbSchema(this.dbs)
			}
		},

		// width: {
		// 	immediate: true,
		// 	handler() {
		// 		this.editor &&
		// 			this.editor.layout({ width: this.width, height: this.height })
		// 	}
		// },
		// height: {
		// 	immediate: true,
		// 	handler() {
		// 		this.editor &&
		// 			this.editor.layout({ width: this.width, height: this.height })
		// 	}
		// },
		theme: {
			immediate: true,
			handler() {
				// 设置编辑器主题
				monaco.editor.setTheme(this.theme)
			}
		},

		selectedCatalog: {
			immediate: true,
			handler() {
				// 设置编辑器主题
				this.sqlSnippets && this.sqlSnippets.setSelectedCatalog(this.selectedCatalog == null ? '' : this.selectedCatalog)
			}
		}
	},
	created() {
		(self as any).MonacoEnvironment = {
			getWorker(_: string, label: string) {
				return new EditorWorker()
			},
		}

		const codeEditBox = ref()

		let completionItemProvider: any;

		const init = () => {
			// 实例化snippets
			this.sqlSnippets = new SQLSnippets(
				monaco,
				this.customKeywords,
				this.selectedCatalog,
				this.onInputField,
				this.onInputTableAlia,
				this.dbs
			)
			// 设置编辑器语言
			completionItemProvider = monaco.languages.registerCompletionItemProvider(
				this.language,
				{
					triggerCharacters: [' ', '.', ...[]],
					provideCompletionItems: (model, position) =>
						this.sqlSnippets.provideCompletionItems(model, position)
				}
			)

			this.editor = monaco.editor.create(this.$refs.codeEditBox, {
				value: this.modelValue,
				language: this.language,
				readOnly: this.readOnly,
				automaticLayout: true,
				...this.options,
			})
			// this.editor = monaco.editor.create(this.$refs.codeEditBox, {
			// 	value: [''].join('\n'),
			// 	language: 'sql',
			// 		...this.options,
			// });
			//  monacoSqlAutocomplete(monaco, this.editor, this.sqlSnippets);			// 重新渲染
			// this.editor.layout({ width: this.width, height: this.height })
			// 监听值的变化
			this.editor.onDidChangeModelContent(() => {
				const value = this.editor.getValue() // 给父组件实时返回最新文本
				this.$emit('update:modelValue', value)
				this.$emit('change', value)
			})
			this.editor.onDidChangeCursorSelection(e => {
				const selectedText = this.editor.getModel().getValueInRange({
					startLineNumber: e.selection.startLineNumber,
					startColumn: e.selection.startColumn,
					endLineNumber: e.selection.endLineNumber,
					endColumn: e.selection.endColumn
				})
				this.$emit('onDidChangeCursorSelection', selectedText)
			})
			this.editor.addCommand(
				monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter,
				() => {
					this.$emit('ctrl-enter')
				}
			)

			this.$emit('editor-mounted', this.editor)
		}




		onBeforeUnmount(() => {
			completionItemProvider&& completionItemProvider.dispose()
			this.editor&&this.editor.dispose()
		})

		onMounted(() => {
			init()
		})

		return { codeEditBox }
	},


	methods: {
		getSelectionVal() {
			const selection = this.editor.getSelection() // 获取光标选中的值
			const { startLineNumber, endLineNumber, startColumn, endColumn } = selection
			const model = this.editor.getModel()

			return model.getValueInRange({
				startLineNumber,
				startColumn,
				endLineNumber,
				endColumn,
			})
		},
		setValue(value){
			this.editor.setValue(value)

		},
		getValueParses(){
			const value = this.editor.getValue() // 给父组件实时返回最新文本
			return this.sqlSnippets.getGenericAutocompleteParser(value);
		}
	}
}

</script>
<style lang="scss" scoped>
// .codeEditBox {
// 	width: 100%;
// 	height: 100%;
// 	flex: 1;
// 	min-height: 500px;
// 	max-height:calc(100vh - 178px);
// 	overflow-y: auto;
// }

// .codeEditBox1 {
// 	height: calc(100% - 323px);
// }
.magic-monaco-editor{
	position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    overflow: visible!important;
}
.magic-monaco-editor :deep(.breakpoints){
    background: var(--breakpoints-background-color);
    width: 10px !important;
    height: 10px !important;
    right: 0px !important;
    margin-left: 12px;
    top: 5px;
    border-radius: 5px;
}
.magic-monaco-editor :deep(.debug-line) {
    background: var(--debug-line-background-color);
    color: #fff !important;
}
.magic-monaco-editor :deep(.breakpoint-line) {
    background: var(--breakpoint-line-background-color);
}
</style>
